cmake_minimum_required(VERSION 3.10)

# 工程名字 以及 版本号
project(Tutorial  VERSION 2.2)

# 指定C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)


include(CheckSymbolExists)
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
if(HAVE_LOG AND HAVE_EXP)
    message(STATUS "all in")
endif()

#-------------------------引入条件变量
option(USE_MYMATH "Use tutorial provided math implementation" ON) 
if(USE_MYMATH)
  set(USE_MYMATH)  #设置  USE_MYMATH 变量
  add_subdirectory(MathFunctions)# 添加子目录
  list(APPEND EXTRA_LIBS MathFunctions) #添加扩展库 MathFunctions 
endif()

##############引入的条件变量都要放在 configure_file 之前


# 项目配置选项文件，此文件可引入外部变量到 源码中
configure_file (
    "${PROJECT_SOURCE_DIR}/include/TutorialConfig.h.in"
    "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)




#-------------------------添加可执行文件
add_executable(Tutorial  tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})# 相当于导入目标依赖库 # 可以使用PUBLIC，PRIVATE和INTERFACE关键字在一个命令中同时指定链接依赖性和链接接口。 PUBLIC之后的库和目标已链接到链接接口，并成为链接接口的一部分。 PRIVATE之后的库和目标已链接到链接接口，但未成为链接接口的一部分。 INTERFACE之后的库被附加到链接接口，并且不用于链接。
target_include_directories(Tutorial PUBLIC   "${PROJECT_BINARY_DIR}" )#相当于导入头文件 # 因为生成的config.h 在 PROJECT_BINARY_DIR 中，所以要引入 #PRIVATE和PUBLIC项目将填充的`INCLUDE_DIRECTORIES`属性。 PUBLIC和INTERFACE项目将填充的INTERFACE_INCLUDE_DIRECTORIES属性。

#-------------------------安装选项
install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
        DESTINATION include  )                           

#-------------------------测试
enable_testing()#对当前目录及以下版本启用测试。 该命令应位于源目录的根目录中，因为ctest希望在构建目录的根目录中找到一个测试文件。

# does the application run
add_test(NAME test1 COMMAND Tutorial 25)  #将测试添加到要由ctest 运行的项目中，相当于是一个测试用例
#add_test(NAME <name> COMMAND <command> [<arg>...])

# does the usage message work?
add_test(NAME test2 COMMAND Tutorial)
set_tests_properties(test2
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
)
# set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2 value2)
# PASS_REGULAR_EXPRESSION ： 程序的输出必须匹配正则表达式，测试才能通过 



# define a function to simplify adding tests
function(do_test target arg result) #函数名 测试程序名 参数 结果
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result} 
  )
endfunction(do_test)

# do a bunch of result based tests
do_test(Tutorial 4 "2")
do_test(Tutorial 9 "3")
do_test(Tutorial 5 "2.236")
do_test(Tutorial 7 "2.645")
do_test(Tutorial 25 "5")
do_test(Tutorial -25 "[-nan|nan|0]")
do_test(Tutorial 0.0001 "0.01")